// 
// 
// 

#include "LiquidLevel.h"
#include "Preferences.h"
#include "capSensor\capSensor.h"
#include "parseCMD.hpp"

#define		MINLEVEL_POS		"MINLEV"
#define		MINRL_POS			"MINRL"
#define		FLAG_POS			"LEVELFLAG"
#define		FLAGVAL				0xA5
#define		BNAME				"Domain_Liquid"
#define		DEFAULTZL			0x11
#define		DEFAULTRL			0x11

extern QueueHandle_t ParaRelease;
extern QueueHandle_t ParaReturn;

static Preferences Mstorage;

static int MinLvl;
static int MinRl;
static float LiquidLevel;

portMUX_TYPE LiquidMux = portMUX_INITIALIZER_UNLOCKED;


static void InitLiquidDetection(void);
static int GetLiquidLevel(void);
static void SetZeroLiquid(int ZL);
static void SetZeroRl(int RL);
static int GetZeroRl(void);
static int GetZeroLiquid(void);
static void LoadData(const char* pos, int* val);
static void SaveData(const char* pos, int val);
static bool IsSaved(void);



void TaskLiquid(void* pvParameters)
{
	InitLiquidDetection();
	ParaConfig_t LvlPara;
	LvlPara.type = dLiquidLevel;
	while (1)
	{
		if (xQueuePeek(ParaRelease, &LvlPara, 0))
		{

			if (LvlPara.type == dLiquidLevel)
			{
				xQueueReceive(ParaRelease, &LvlPara, 0);
				if (LvlPara.WR == cR)
				{
					LvlPara.para = GetLiquidLevel();
					xQueueSend(ParaReturn, &LvlPara, 0x10);
				}
				else
				{
					switch (LvlPara.subtype)
					{
					case SetLvl0:
						SetZeroLiquid(LvlPara.para);
						break;
					case SetRl:
						SetZeroRl(LvlPara.para);
						break;
					default:
						break;
					}
				}
			}			
		}
		vTaskDelay(10);
	}
}

static void InitLiquidDetection(void)
{
	if (IsSaved())
	{
		GetZeroLiquid();
		GetZeroRl();
	}
	else
	{
		SetZeroLiquid(DEFAULTZL);
		SetZeroRl(DEFAULTRL);
	}
}

static int GetLiquidLevel(void)
{
	int  M1 = 0, M2 = 0;
	for (uint8_t i = 0; i < 5; i++)
	{
		M1 += CapSensor::read_Meas1() / 256;
		M2 += CapSensor::read_Meas2() / 256;
	}
	if (M2 < 330000)
	{
		return 0;
	}
	return max(((float)M1 - (float)MinLvl) / ((float)M2 - (float)MinRl), (float)0);
}

static void SetZeroLiquid(int ZL)
{
	MinLvl = ZL;
	SaveData(MINLEVEL_POS, MinLvl);
}

static void SetZeroRl(int RL)
{
	MinRl = RL;
	SaveData(MINRL_POS, MinRl);
}

static int GetZeroLiquid(void)
{
	LoadData(MINLEVEL_POS, &MinLvl);
	return MinLvl;
}

static int GetZeroRl(void)
{
	LoadData(MINRL_POS, &MinRl);
	return MinRl;
}

static void SaveData(const char* pos, int val)
{
	Mstorage.begin(BNAME);
	Mstorage.putInt(pos, val);
	Mstorage.putInt(FLAG_POS, FLAGVAL);
	Mstorage.end();
}

static void LoadData(const char* pos, int* val)
{
	Mstorage.begin(BNAME);
	val[0] = Mstorage.getInt(pos);
	Mstorage.end();
}

static bool IsSaved(void)
{
	int flag;
	LoadData(FLAG_POS, &flag);
	return (flag == FLAGVAL);
}